home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Kernel / Em / utils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-17  |  32.2 KB  |  1,044 lines

  1.  
  2. /*
  3.  * @(#)utils.c    1.4  2/23/90
  4.  */
  5.  
  6. /* Copyright 1986 Eric Jul.  May not be used for any purpose without    */
  7. /* written permission from the author.                            */
  8. /* The Emerald kernel for the Emerald programming language.             */
  9.  
  10. /* This file contains the implementation of a number of utilities.      */
  11. /* Most of these procedures take a reference to some data structure     */
  12. /* and return a printable string.   Most are for debugging and test     */
  13. /* output (traces and snapshots).                                       */
  14.  
  15. #include <stdio.h>
  16.  
  17. #include "Kernel/h/system.h"
  18. #include "Kernel/h/assert.h"
  19. #include "Kernel/h/emTypes.h"
  20. #include "Kernel/h/kmdTypes.h"
  21. #include "Kernel/h/mmMsgTypes.h"
  22. #include "Kernel/h/lmTypes.h"
  23. #include "Kernel/h/emkDefs.h"
  24. #include "Kernel/h/consts.h"
  25. #include "Kernel/h/kEvents.h"
  26.  
  27. extern char                    *sbrk();
  28.  
  29. extern ODP                      OTLookup();
  30. extern Boolean                  SSValidAddr();
  31. extern int                      etext;
  32.  
  33. /* Forward */
  34. char                           *PPODBasicTag();
  35.  
  36. char  *BasicTagName[] = {
  37.     "InvalidTag",
  38.         "UnknownTag",
  39.         "GODTag",
  40.     "GODataTag",
  41.         "SSODTag",
  42.         "SSTag",
  43.         "CodeODTag",
  44.         "CodeTag",
  45.         "LOTag",
  46.         "ProcessODTag",
  47.         "AbConTag",
  48.         "CondTag",
  49.     "DotoTag",
  50.         "LastODBasicTag"    /* Must be last tag AND have this name */
  51. };
  52.  
  53. char *ParamInfoNames[] = {
  54.     "Is not parameter",
  55.     "Is argument",
  56.     "Is result",
  57.     "Is return-by-move result"
  58. };
  59.  
  60. char *BrandNames[] = {
  61.         "DataBrand",
  62.         "ODPBrand",
  63.         "AddrBrand",
  64.         "VectorBrand",
  65.         "VariableBrand",
  66.         "MonitorLockBrand",
  67.         "InvokeQueueBrand",
  68.         "UnusedBrand"
  69. };
  70.  
  71. char *ITagNames[] = {
  72.         "INVALIDITAG",      /* Must be the first tag */
  73.  
  74.         "InvokeITag",
  75.         "ReplyITag",
  76.         "RemoteLoadReqITag",
  77.         "CodeTransferITag",
  78.         "ParamTag",
  79.         "ConfirmITag",
  80.         "ShoutITag",
  81.         "SearchITag",
  82.         "ConfirmReplyITag",
  83.         "ShoutReplyITag",
  84.         "SearchReplyITag",
  85.         "PingITag",
  86.         "PongITag",
  87.         "PingTimingITag",
  88.         "PongTimingITag",
  89.         "MoveITag",
  90.         "MoveReplyITag",
  91.  
  92.         "TTFirstITag",      /* Must be the first TT tag */
  93.         "TTGODITag",          
  94.         "TTSSODITag",
  95.         "TTCodeODITag",
  96.         "TTAbConITag",
  97.         "TTGODataITag",
  98.         "TTLOITag",
  99.         "TTROITag",
  100.         "TTMoveGODITag",
  101.         "TTMoveSSODITag",
  102.         "TTMoveCITag",
  103.         "TTFetchGODITag",
  104.         "TTCodeAddrITag",
  105.         "TTInvokeITag",
  106.         "TTIncomingIITag",
  107.         "TTCondITag",
  108.         "TTMoveCondITag",
  109.         "TTLastITag",       /* Must be the last TT tag */
  110.     
  111.         "LastITag"         /* Must be the very last tag AND have this name */
  112.  
  113. };
  114.  
  115. char *RTagNames[] = {
  116.         "INVALID ZERO RTag!!",
  117.         "InvokeRTag",
  118.         "IncomingIRTag",
  119.         "LocateRTag",
  120.         "MoveRTag",
  121.         "StackBreakRTag",
  122.         "CompilerLoadRTag",
  123.         "CodeLoadRTag",
  124.         "CheatingLoadRTag",
  125.         "InitiallyRTag",
  126.         "ConformRTag",
  127.         "ViewRTag",
  128.         "IncomingMoveRTag",
  129.         "OwnRTag",
  130.         "CondWaitRTag",
  131.         "MonWaitRTag",
  132.         "TimedWaitRTag",
  133.  
  134.         "LastRTag"               /* Must be last RTag */
  135. };
  136.  
  137. char *SSRunStatusNames[] = {
  138.     "NotInUse",
  139.     "Allocated",
  140.     "Runnable",
  141.     "Condition Wait",
  142.     "Monitor Entry Wait",
  143.     "Req Wait",
  144.     "Invoke Wait",
  145.     "Timer Wait",
  146.     "Initially Wait",
  147.     "Move Wait",
  148.     "Locate Wait",
  149.         "Conform Wait",
  150.         "Read IO Wait",
  151.         "Write IO Wait",
  152.         "Own Wait",
  153.         "Broken & dead",
  154.  
  155.     "LastRunStatus"      /* Must be last enum in SSRunStatus */
  156. };
  157.  
  158. typedef struct BitDescription {
  159.     unsigned int        position;
  160.     char               *name;
  161.     char               *printableValue[2];
  162. } BitDescription;
  163.  
  164. #define END_MARK        3333
  165.  
  166. BitDescription          bitD[] = {
  167.     { ODTag_frozen,     "frozen",       {"", "FROZEN"}},
  168.     { ODTag_global,     "global",       {"local", "global"}},
  169.     { ODTag_replicated, "replicated",   {"", "repl"}},
  170.     { ODTag_isResident, "isResident",   {"remote", "resident"}},
  171.     { ODTag_setUpDone,  "setUpDone",    {"~init", "initOK"}},
  172.     { ODTag_isFixed,    "isFixed",      {"", "Fxd"}},
  173.     { ODTag_inTransit,  "inTransit",    {"", "transit"}},
  174.     { ODTag_allInstancesAreLocal,   "allInstancesAreLocal", {"", "allLocal"}},
  175.     { ODTag_hasNoPointer,   "hasNoPointer", {"", "noPtr"}},
  176.     { ODTag_broken,     "broken",       {"", "BROKEN"}},
  177.     { ODTag_gcDoNotCollect, "gcDoNotCollect",   {"", "KEEP"}},
  178.     { ODTag_gcMark1,    "gcMark1",      {"", "1"}},
  179.     { ODTag_gcMark2,    "gcMark2",      {"", "2"}},
  180.     { ODTag_gcFrozen,   "gcFrozen",     {"", "gcFz"}},
  181.     { ODTag_localgcMark1,   "localgcMark1", {"", "l1"}},
  182.     { ODTag_localgcMark2,   "localgcMark2", {"", "l2"}},
  183.     { ODTag_xref,  "xref",    {"", "xref"}},
  184.     { ODTag_dormant,    "dormant",      {"", "dormant"}},
  185.     { ODTag_stopped,    "stopped",      {"", "stopped"}},
  186.     { ODTag_seenHere,   "seenHere",     {"", "seenH"}},
  187.     { END_MARK,         "END_MARK",     {"", ""}}
  188. };
  189.  
  190. unsigned int            validMask[32];
  191.  
  192. /************************************************************************/
  193. /*  PPValid                                                             */
  194. /************************************************************************/
  195. Boolean PPValidAddr(fAddr)
  196. SSAddr             *fAddr;
  197. /* True iff fAddr is an address in the data area */
  198. {
  199.     return (&etext < (int *) fAddr && (int *)fAddr < (int *) sbrk(0));
  200. }
  201.  
  202. /************************************************************************/
  203. /*  IPMapLookup                                                         */
  204. /************************************************************************/
  205. Offset IPMapLookup(fMap, fOffset)
  206. register IPMapPtr        fMap;
  207. register Offset          fOffset;
  208. /* Given a map and an offset, return the associated data item */
  209. /* The map must exist */
  210. {
  211.     register IPMapEntryPtr  entry;
  212.     if ((fOffset > fMap->highestIPOffset)||(fOffset < fMap->lowestIPOffset)){
  213.     return (Offset) 0;
  214.     };
  215.     entry = & fMap->mapEntries[0];
  216.     while (fOffset > entry->highIPOffset) entry++;
  217.     return entry->offset;
  218. }
  219.  
  220. /************************************************************************/
  221. /*  SSDownOne                                                           */
  222. /*  Given a pointer to an activation record, return a pointer to the    */
  223. /*  caller activation record.                                           */
  224. /************************************************************************/
  225. SSAddr SSDownOne(fL)
  226. SSAddr      fL;
  227. {
  228.     return mDynLinkPtrFromL(fL)->l;
  229. }
  230.  
  231.  
  232. /************************************************************************/
  233. /*  PP procedures generate printable ASCII strings for stuff            */
  234. /************************************************************************/
  235.  
  236. /* Buffers are managed cyclically -- do not save the buf ptr for long! */
  237. #define NBUFS 20
  238. int     next = 0;
  239. char    buffers[NBUFS][300];
  240. char    overrunarea[200];  /* In case the buffers area should overflow */
  241.  
  242. char *getNextBuf()
  243. {
  244.     return buffers[(++next >= NBUFS ? next = 0 : next)];
  245. }
  246.  
  247. /************************************************************************/
  248. /*  ValidSSPtr                                                          */
  249. /*  Given a SSPtr, check it for validity                                */
  250. /************************************************************************/
  251. Boolean ValidSSPtr(fSSPtr)
  252. SSPtr               fSSPtr;
  253. {
  254.     if (!PPValidAddr((SSAddr *) fSSPtr)) return FALSE;
  255.     if (fSSPtr->tag.tag != SSTag) return FALSE;
  256.     if (fSSPtr->tag.otherstuff != OBSCUREVALUE) return FALSE;
  257.     return TRUE;
  258. }
  259.  
  260. /************************************************************************/
  261. /*  SSValidAddr                                                         */
  262. /*  Given a stack address and a stack pointer, validate the addr        */
  263. /************************************************************************/
  264. Boolean SSValidAddr(fSSPtr, fAddr)
  265. SSPtr           fSSPtr;
  266. SSAddr          fAddr;
  267. /* SSValidAddr checks to see whether the given address is inside the stack
  268.    segment. */
  269. {
  270.     return ValidSSPtr(fSSPtr) && 
  271.     ((fAddr >= fSSPtr->regs.sp) && (fAddr < fSSPtr->endOfSS));
  272. }
  273.  
  274. /************************************************************************/
  275. /*  SSHighAddr                                                          */
  276. /************************************************************************/
  277. SSAddr SSHighAddr(fSSPtr)
  278. register SSPtr                   fSSPtr;
  279. /* Return the highest address of the Stack Segment.  Following conventions,
  280.    this address is the address of the first byte AFTER the SS */
  281. {
  282.     return ((SSAddr) fSSPtr->endOfSS);
  283. }
  284.  
  285. /************************************************************************/
  286. /*  PPString                                                            */
  287. /************************************************************************/
  288. char *PPString(fStrPtr)
  289. StringPtr       fStrPtr;
  290. /* Given a ptr for an Emerald string, return a ptr to a C string */
  291. {
  292.     char *buf = getNextBuf();
  293.     if (fStrPtr == (StringPtr) EMNIL) {
  294.     (void) sprintf(buf, "[EMNIL]");
  295.     } else {
  296.     (void) sprintf(buf, "%.*s", fStrPtr->sizeInBytes, (char *)&fStrPtr->data[0]);
  297.     }
  298.     return buf;
  299. }
  300.  
  301. /************************************************************************/
  302. /*  PPCName                                                             */
  303. /************************************************************************/
  304. char *PPCName(fCodePtr)
  305. register CodePtr         fCodePtr;
  306. /* Given a CodePtr for some code, return a string to print */
  307. {
  308.     register StringPtr  nameAddr;
  309.     char *buf = getNextBuf();
  310.     
  311.     if (IsNULL(fCodePtr)) {
  312.     (void) sprintf(buf, "NULL");
  313.     } else if ((!PPValidAddr((SSAddr *) fCodePtr))
  314.     ||(fCodePtr->tag.tag != CodeTag)) {
  315.     (void) sprintf(buf, "INVALID");
  316.     } else if (IsNULL(fCodePtr->codeNameOffset)){
  317.     (void) sprintf(buf, "NAMELESS");
  318.     } else {
  319.     nameAddr = (StringPtr) addOffset(fCodePtr, fCodePtr->codeNameOffset);
  320.         if (!PPValidAddr((SSAddr *) nameAddr)) {
  321.         (void) sprintf(buf, "Code: Invalid name or code");
  322.         return buf;
  323.     }
  324.     return PPString(nameAddr);
  325.     }
  326.     return buf;
  327. }
  328.  
  329. /************************************************************************/
  330. /*  PPCodePtr                                                           */
  331. /************************************************************************/
  332. char *PPCodePtr(fCodePtr)
  333. CodePtr          fCodePtr;
  334. /* Given a CodePtr for some code object, return a string to print */
  335. {
  336.     char *buf = getNextBuf();
  337.     
  338.     if (IsNIL(fCodePtr) || IsNULL(fCodePtr) ||
  339.     (!PPValidAddr((SSAddr *) fCodePtr)) || fCodePtr->tag.tag != CodeTag) {
  340.     (void) sprintf(buf, "CODEPTR(0x%02x)", fCodePtr);
  341.     } else {
  342.     if (fCodePtr->tag.tag != CodeTag) {
  343.         (void) sprintf(buf, "C%08.8x", fCodePtr->ownOID);
  344.     } else {
  345.         (void) sprintf(buf, "C%08.8x (%s)", fCodePtr->ownOID, PPCName(fCodePtr));
  346.     }
  347.     }
  348.     return buf;
  349. }
  350.     
  351. /************************************************************************/
  352. /*  PPCOID                                                              */
  353. /************************************************************************/
  354. char *PPCOID(fCOID)
  355. OID          fCOID;
  356. /* Given an OID for some code object, return a string to print */
  357. {
  358.     char *buf = getNextBuf();
  359.     CodeODP         cODP;
  360.  
  361.     if (IsNULL(fCOID)) {
  362.     (void) sprintf(buf, "NULL CODEOID");
  363.     } else if (IsNIL(fCOID)) {
  364.     (void) sprintf(buf, "NIL CODEOID");
  365.     } else {
  366.     cODP = (CodeODP) OTLookup(fCOID);
  367.     if (IsNULL(cODP) || cODP->tag.tag != CodeODTag || IsNULL(cODP->dataPtr)) {
  368.         (void) sprintf(buf, "C%08.8x", fCOID);
  369.     } else {
  370.         (void) sprintf(buf, "C%08.8x (%s)", fCOID, PPCName(cODP->dataPtr));
  371.     }
  372.     }
  373.     return buf;
  374. }
  375.  
  376. /************************************************************************/
  377. /*  PPOID                                                               */
  378. /************************************************************************/
  379. char *PPOID(fOID)
  380. OID          fOID;
  381. /* Given an OID for something return a string */
  382. {
  383.     char *buf = getNextBuf();
  384.     (void) sprintf(buf, "0x%08.8x", fOID);
  385.     return buf;
  386. }
  387.  
  388. /************************************************************************/
  389. /*  PPPOID                                                              */
  390. /************************************************************************/
  391. char *PPPOID(fPOID)
  392. OID          fPOID;
  393. /* Given an OID for a process return a printable version */
  394. {
  395.     char *buf = getNextBuf();
  396.     (void) sprintf(buf, "P%08.8x", fPOID);
  397.     return buf;
  398. }
  399.  
  400. /************************************************************************/
  401. /*  PPGOID                                                              */
  402. /************************************************************************/
  403. char *PPGOID(fGOID)
  404. OID          fGOID;
  405. /* Given an OID for some global object, return a string to print */
  406. {
  407.     char *buf = getNextBuf();
  408.     if (fGOID == (OID) NULL) {
  409.     (void) sprintf(buf, "ANONYMOUS");
  410.     } else {
  411.     (void) sprintf(buf, "G%08.8x", fGOID);
  412.     }
  413.     return buf;
  414. }
  415. /************************************************************************/
  416. /*  PPLoc                                                               */
  417. /************************************************************************/
  418. char *PPLoc(fLoc)
  419. EmLocation              fLoc;
  420. /* Return printable string for location */
  421. {
  422.     register EmLocationStructPtr theLoc;
  423.     char               *buf = getNextBuf();
  424.  
  425.     theLoc              = (EmLocationStructPtr) &fLoc;
  426.     if (theLoc->timestamp == 0) {
  427.     (void) sprintf(buf, "LOC UNKNOWN");
  428.     } else {
  429.     (void) sprintf(buf, "<%2u, #%2u>", theLoc->timestamp, theLoc->lnn);
  430.     }
  431.     return buf;
  432. }
  433.  
  434. /************************************************************************/
  435. /*  PPVar                                                               */
  436. /************************************************************************/
  437. char *PPVar(fVarAddr)
  438. AVariablePtr            fVarAddr;
  439. /* Given the address of a variable,  return a string to print */
  440. {
  441.     char               *buf = getNextBuf();
  442.     ODP                 theODP;
  443.     
  444.     if (IsNULL(fVarAddr)) {
  445.     (void) sprintf(buf, "(NULL VARADDR)");
  446.     } else if ((int *) fVarAddr < &etext) {
  447.     (void) sprintf(buf, "(ADDR 0x%01x TOO SMALL)", fVarAddr);
  448.     } else if (((int *) fVarAddr > (int *) sbrk(0)) &&
  449.         !(   ((int *) fVarAddr < (int *) 0x7ffffff0) && /* could be on stack*/
  450.              ((int *) fVarAddr > (int *) 0x7f000000)
  451.     )
  452.     ) {
  453.     (void) sprintf(buf, "(ADDR 0x%01x TOO LARGE)", fVarAddr);
  454.     } else if (IsNIL(fVarAddr->myAbConPtr) || IsNIL(fVarAddr->myAddr)) {
  455.     (void) sprintf(buf, "(NIL)");
  456.     } else if (!PPValidAddr((SSAddr *) fVarAddr->myAbConPtr)
  457.         || (fVarAddr->myAbConPtr->tag.tag != AbConTag)) {
  458.     theODP = (ODP) fVarAddr->myAddr;
  459.     (void) sprintf(buf, "(0x%05x, 0x%05x)", theODP, fVarAddr->myAbConPtr);
  460.     } else {
  461.     theODP = (ODP) fVarAddr->myAddr;
  462.     (void) sprintf(buf, "(0x%01x) one of %s viewed as %s", theODP,
  463.         PPCOID(fVarAddr->myAbConPtr->CodeOID),
  464.         PPCOID(fVarAddr->myAbConPtr->ATOID));
  465.     };
  466.     return buf;
  467. }
  468.  
  469. /************************************************************************/
  470. /*  PPODP                                                               */
  471. /************************************************************************/
  472. char *PPODP(fODP)
  473. ODP                 fODP;
  474. /* Given an ODP, return a string describing it */
  475. {
  476.     char               *buf = getNextBuf();
  477.     
  478.     if (IsNIL(fODP)) {
  479.     (void) sprintf(buf, "NIL");
  480.     } else if (IsNULL(fODP)) {
  481.     (void) sprintf(buf, "NULL");
  482.     } else if ((int *) fODP < &etext) {
  483.     (void) sprintf(buf, "(ADDR 0x%01x TOO SMALL)", fODP);
  484.     } else if ((int *) fODP > (int *) sbrk(0)) {
  485.     (void) sprintf(buf, "(ADDR 0x%01x TOO LARGE)", fODP);
  486.     } else if (fODP->G.tag.tag == GODTag) {
  487.     (void) sprintf(buf, "GOD, one of %s", PPCOID(fODP->G.myCodeOID));
  488.     } else if ((fODP->G.tag.tag == GODataTag) ||(fODP->G.tag.tag == LOTag)) {
  489.     (void) sprintf(buf, "0x%06x (one of %s)", fODP,
  490.         PPCodePtr(fODP->L.myCodePtr));
  491.     } else {
  492.     (void) sprintf(buf, "(0x%06x, %s)", fODP, PPODBasicTag(fODP->G.tag.tag));
  493.     };
  494.     return buf;
  495. }
  496.  
  497. /************************************************************************/
  498. /*  PPFindLineNo                                                        */
  499. /************************************************************************/
  500. char *PPFindLineNo(fCodeP, fip)
  501. CodePtr             fCodeP;
  502. CodeAddr            fip;
  503. /* Given a code ptr and a ip, return the line number (0, if none) */
  504. {
  505.     char           *buf = getNextBuf();
  506.     Offset          ipRelative;
  507.     IPMapPtr        mapAddr;
  508.     int             lineNumber;
  509.  
  510.     if (PPValidAddr((SSAddr *) fCodeP) && (fCodeP->tag.tag == CodeTag) &&
  511.         PPValidAddr((SSAddr *) &fCodeP->lineNumberMapOffset) &&
  512.     NonNULL(fCodeP->lineNumberMapOffset)) {
  513.     ipRelative = (Offset) byteOffset(fCodeP, fip);
  514.     mapAddr = (IPMapPtr) addOffset(fCodeP, fCodeP->lineNumberMapOffset);
  515.     lineNumber = (int) IPMapLookup(mapAddr, ipRelative);
  516.     (void) sprintf(buf, "%d", lineNumber);
  517.     } else {
  518.     (void) sprintf(buf, "<LINENUMBER NOT AVAILABLE>");
  519.     }
  520.     return buf;
  521. }
  522.  
  523. /************************************************************************/
  524. /*  PPRegsPlace                                                         */
  525. /************************************************************************/
  526. char *PPRegsPlace(fRegsPtr, fCurrentIP)
  527. RegisterSavePtr         fRegsPtr;
  528. CodeAddr                fCurrentIP;
  529. /* Given a pointer to a set of registers, find the AR place and 
  530. return a string to print "<object name>, line xxx" */
  531. {
  532.     char *buf = getNextBuf();
  533.     GODataPtr   g;
  534.     CodePtr     cPtr;
  535.     
  536.     if (NonNULL(fRegsPtr->l)){
  537.     g           =  (GODataPtr)  (fRegsPtr->g);
  538.         if (!PPValidAddr((SSAddr *) g)) {
  539.         (void) sprintf(buf, "BAD OBJECT REFERENCE 0x%06x", g);
  540.         return buf;
  541.     }
  542.     cPtr        = g->myCodePtr;
  543.     (void) sprintf(buf, "\"%s\", line %s", PPCName(cPtr),
  544.         PPFindLineNo(cPtr, fCurrentIP));
  545.     } else {
  546.     (void) sprintf(buf, "\"** Empty Stack **\"");
  547.     }
  548.     return buf;
  549. }
  550.  
  551.  
  552. /************************************************************************/
  553. /*  PPSSPlace                                                           */
  554. /************************************************************************/
  555. char *PPSSPlace(fSSPtr)
  556. SSPtr           fSSPtr;
  557. /* Given a SSPtr, return a string to print "<object name>, line xxx" */
  558. {
  559.     char *buf = getNextBuf();
  560.     CodeAddr    ip;
  561.     GODataPtr   g;
  562.     CodePtr     cPtr;
  563.     
  564.     if (!ValidSSPtr(fSSPtr)) return "Invalid SSPtr";
  565.  
  566.     if (!PPValidAddr((SSAddr *) fSSPtr->regs.b)) {
  567.     (void) sprintf(buf, "SS has invalid b = 0x%06x", fSSPtr->regs.b);
  568.     return buf;
  569.     }
  570.     
  571.     if (!PPValidAddr((SSAddr *) fSSPtr->regs.g)) {
  572.     (void) sprintf(buf, "SS has invalid g = 0x%06x", fSSPtr->regs.g);
  573.     return buf;
  574.     }
  575.     
  576.     if (
  577.         SSValidAddr(fSSPtr, fSSPtr->regs.l) &&
  578.         SSValidAddr(fSSPtr, fSSPtr->regs.sp)
  579.     ) {
  580.     ip = * (CodeAddr *) (fSSPtr->regs.sp);
  581.     g =  (GODataPtr)  (fSSPtr->regs.g);
  582.     cPtr = g->myCodePtr;
  583.     (void) sprintf(buf, "\"%s\", line %s", PPCName(cPtr),
  584.         PPFindLineNo(cPtr, ip));
  585.     } else {
  586.     (void) sprintf(buf, "\"** Empty Stack **\"");
  587.     }
  588.     return buf;
  589. }
  590.  
  591. /**********************************************************************/
  592. /*  PPPrintPos, PPGetPos                                              */
  593. /**********************************************************************/
  594. char *PPGetPos(fG, fIp)
  595. unsigned int fG, fIp;
  596. /* For debugging */
  597. {
  598.     char *buf = getNextBuf();
  599.     unsigned int    limit;
  600.     CodePtr         cPtr;
  601.  
  602.     limit = (unsigned int) sbrk(0);
  603.     if ((fIp > limit) || (fIp < (unsigned int) &etext)) {
  604.     (void) sprintf(buf, "Invalid ip value 0x%06x\n", fIp);
  605.     return buf;
  606.     }
  607.     
  608.     if ((fG > limit) ||
  609.     (fG < (unsigned int) &etext) ||
  610.     ( (((GODataPtr) fG)->tag.tag != GODataTag) &&
  611.       (((GODataPtr) fG)->tag.tag != LOTag)
  612.     ) ||
  613.     (((GODataPtr) fG)->tag.otherstuff != OBSCUREVALUE) )
  614.     {
  615.     (void) sprintf(buf, "Invalid object pointer 0x%06x\n", fG);
  616.     return buf;
  617.     }
  618.     cPtr = ((GODataPtr) fG)->myCodePtr;
  619.     if (((unsigned int) cPtr > limit) ||
  620.     ((unsigned int) cPtr < (unsigned int) &etext) ||
  621.     (cPtr->tag.tag != CodeTag) ||
  622.     (cPtr->tag.otherstuff != OBSCUREVALUE) ) {
  623.     (void) sprintf(buf, "Invalid code pointer 0x%06x\n", cPtr);
  624.     return buf;
  625.     }
  626.  
  627.     (void) sprintf(buf, "\"%s\", line %s\n", PPCName(cPtr),
  628.     PPFindLineNo(((GODataPtr)fG)->myCodePtr, (CodeAddr) fIp));
  629.     return buf;
  630. }
  631.  
  632.  
  633. /**********************************************************************/
  634. /*  PPPrintPos                                                        */
  635. /**********************************************************************/
  636. void PPPrintPos(fG, fIp)
  637. unsigned int fG, fIp;
  638. /* For debugging;  callable from dbx - can be useful */
  639. {
  640.     unsigned int    limit;
  641.     CodePtr         cPtr;
  642.  
  643.     limit = (unsigned int) sbrk(0);
  644.     if ((fIp > limit) || (fIp < (unsigned int) &etext)) {
  645.     printf("Bogus ip value 0x%06x\n", fIp);
  646.     return;
  647.     }
  648.     
  649.     if ((fG > limit) || (fG < (unsigned int) &etext) ||
  650.     (((GODataPtr) fG)->tag.tag != GODataTag) ||
  651.     (((GODataPtr) fG)->tag.otherstuff != OBSCUREVALUE) ){
  652.     printf("Bogus fG 0x%06x\n", fG);
  653.     return;
  654.     }
  655.     cPtr = ((GODataPtr) fG)->myCodePtr;
  656.     if (((unsigned int) cPtr > limit) ||
  657.     ((unsigned int) cPtr < (unsigned int) &etext) ||
  658.     (cPtr->tag.tag != CodeTag) ||
  659.     (cPtr->tag.otherstuff != OBSCUREVALUE) ) {
  660.     printf("Bogus CodePtr 0x%06x\n", cPtr);
  661.     return;
  662.     }
  663.  
  664.     printf("\"%s\", line %s\n", PPCName(cPtr),
  665.     PPFindLineNo(((GODataPtr)fG)->myCodePtr, (CodeAddr) fIp));
  666. }
  667.  
  668.  
  669.  
  670. /**********************************************************************/
  671. /**********************************************************************/
  672.  
  673. /**********************************************************************/
  674. /*      PPODBasicTag                                                  */
  675. /**********************************************************************/
  676.  
  677. char *PPODBasicTag(fTag)
  678. ODBasicTag              fTag;
  679. /* Return a printable string representation for the tag. */
  680. /* I.e., ODBasicTag.asString */
  681. {
  682.     char               *buf = getNextBuf();
  683.     unsigned int        index;
  684.     
  685.     index               = (unsigned int) fTag;
  686.     
  687.     if (index < (unsigned int) (LastODBasicTag)) {
  688.     return BasicTagName[index];
  689.     }
  690.     (void) sprintf(buf, "INVALID TAG #0x%02x", index);
  691.     return buf;
  692. }
  693.  
  694. /**********************************************************************/
  695. /*      PPODTag                                                       */
  696. /**********************************************************************/
  697. char *PPODTag(fTag)
  698. ODTag                   fTag;
  699. /* return a printable version of the tag, i.e., ODTag.asString */
  700. {
  701.     char               *buf = getNextBuf();
  702.     unsigned int        rawTag, mask, index, i, bit, bitValue;
  703.     
  704.     (void) strcpy(buf, PPODBasicTag(fTag.tag));
  705.     if (fTag.otherstuff != OBSCUREVALUE) {
  706.     (void) strcat(buf, " ");
  707.     (void) strcat(buf, "**TRASHED**");
  708.     }
  709.     
  710.     index               = (unsigned int) fTag.tag;
  711.     
  712.     assert(sizeof(ODTag) == sizeof(unsigned int));
  713.     
  714.     bcopy((char *) &fTag, (char *) &rawTag, sizeof(unsigned int));
  715.     mask                = ~0;
  716.     if (index < (unsigned int) LastODBasicTag) {
  717.     /* Mask out irrelevant bits */
  718.     mask            &= validMask[index];
  719.     }
  720.     
  721.     for (i = 0; bitD[i].position != END_MARK; i++) {
  722.     bit = bitD[i].position;
  723.     if (!((1 << bit) & mask)) continue;
  724.     /* Bit #bit is releveant */
  725.     bitValue        = ((1 << bit) & rawTag) ? 1 : 0;
  726.     (void) strcat(buf, " ");
  727.     (void) strcat(buf, bitD[i].printableValue[bitValue]);
  728.     }
  729.     return buf;
  730. }
  731.  
  732. /**********************************************************************/
  733. /*      PPLocalGCBits                                                 */
  734. /**********************************************************************/
  735. char *PPLocalGCBits(fODP)
  736. ODP                 fODP;
  737. {
  738.     char               *buf = getNextBuf();
  739.  
  740.     if (fODP->G.tag.localgcMark1) {
  741.     if (fODP->G.tag.localgcMark2) {
  742.         strcpy(buf, "Black");
  743.     } else {
  744.         strcpy(buf, "Grey");
  745.     }
  746.     } else {
  747.     if (fODP->G.tag.localgcMark2) {
  748.         strcpy(buf, "INVALIDLOCALGCMARK");
  749.     } else {
  750.         strcpy(buf, "White");
  751.     }
  752.     }
  753.     return buf;
  754. }
  755.  
  756. /**********************************************************************/
  757. /*      PPBrand                                                       */
  758. /**********************************************************************/
  759.  
  760. char *PPBrand(fBrand)
  761. Brand                   fBrand;
  762. /* Return a printable string representation for Brand. */
  763. /* I.e., Brand.asString */
  764. {
  765.     char               *buf = getNextBuf();
  766.     unsigned int        index;
  767.     
  768.     index               = (unsigned int) fBrand;
  769.  
  770.     if (index < (unsigned int) (UnusedBrand)) {
  771.     return BrandNames[index];
  772.     }
  773.     (void) sprintf(buf, "INVALID BRAND #0x%02x", index);
  774.     return buf;
  775. }
  776.  
  777. /**********************************************************************/
  778. /*      PPParamInfo                                                   */
  779. /**********************************************************************/
  780.  
  781. char *PPParamInfo(fParamInfo)
  782. ParamInfo        fParamInfo;
  783. /* Return a printable string representation for Brand. */
  784. /* I.e., Brand.asString */
  785. {
  786.     char               *buf = getNextBuf();
  787.     unsigned int        index;
  788.     
  789.     index               = (unsigned int) fParamInfo;
  790.  
  791.     if (index < (unsigned int) (UnusedBrand)) {
  792.     return ParamInfoNames[index];
  793.     }
  794.     (void) sprintf(buf, "INVALID BRAND #0x%02x", index);
  795.     return buf;
  796. }
  797.  
  798. /**********************************************************************/
  799. /*      PPITag                                                        */
  800. /**********************************************************************/
  801.  
  802. char *PPITag(fITag)
  803. ITag                    fITag;
  804. /* Return a printable string representation for ITag. */
  805. /* I.e., ITag.asString */
  806. {
  807.     char               *buf = getNextBuf();
  808.     unsigned int        index;
  809.     
  810.     index               = (unsigned int) fITag;
  811.     
  812.     if (index < (unsigned int) (LastITag)) {
  813.         (void) strcpy(buf, ITagNames[index]);
  814.         return buf;
  815.     }
  816.     
  817.     (void) sprintf(buf, "INVALID ITag #0x%02x", index);
  818.     return buf;
  819. }
  820.  
  821. /**********************************************************************/
  822. /*      PPRTag                                                        */
  823. /**********************************************************************/
  824.  
  825. char *PPRTag(fRTag)
  826. ReqTag                  fRTag;
  827. /* Return a printable string representation for ReqTag. */
  828. /* I.e., ReqTag.asString */
  829. {
  830.     char               *buf = getNextBuf();
  831.     unsigned int        index;
  832.     
  833.     index               = (unsigned int) fRTag;
  834.     
  835.     if (index < (unsigned int) (LastRTag)) {
  836.         (void) strcpy(buf, RTagNames[index]);
  837.         return buf;
  838.     }
  839.     
  840.     (void) sprintf(buf, "INVALID RTag #0x%02x", index);
  841.     return buf;
  842. }
  843.  
  844. /**********************************************************************/
  845. /*      PPSSRunStatus                                                 */
  846. /**********************************************************************/
  847. char *PPSSRunStatus(fStatus)
  848. {
  849.     char               *buf = getNextBuf();
  850.     unsigned int        index;
  851.     
  852.     index               = (unsigned int) fStatus;
  853.     
  854.     if (index < (unsigned int) (SSLastRunStatus)) {
  855.         (void) strcpy(buf, SSRunStatusNames[index]);
  856.         return buf;
  857.     }
  858.     
  859.     (void) sprintf(buf, "INVALID SSRunStatus #0x%02x", index);
  860.  
  861.     return buf;
  862. }
  863.  
  864. /**********************************************************************/
  865. /*      PPInvokeResult                                                */
  866. /**********************************************************************/
  867. char *PPInvokeResult(fInvokeResult)
  868. InvokeResult        fInvokeResult;
  869. {
  870.     char               *buf = getNextBuf();
  871.     switch (fInvokeResult) {
  872.  
  873.     case INVOKEDONE: {
  874.     strcpy(buf, "INVOKE DONE");
  875.         break;
  876.     }
  877.     
  878.     case INVOKEUNAVAILABLE: {
  879.     strcpy(buf, "INVOKED OBJECT UNAVAILABLE");
  880.         break;
  881.     }
  882.     
  883.     case INVOKEFAILED: {
  884.     strcpy(buf, "INVOKE FAILED");
  885.         break;
  886.     }
  887.     
  888.     default: {
  889.     (void) sprintf(buf, "BAD INVOKE RESULT %d", fInvokeResult);
  890.     break;
  891.     }
  892.     }
  893.     return buf;
  894. }
  895.  
  896. /**********************************************************************/
  897. /*  Doubly linked queue operations                                    */
  898. /*  Provide access to the insque and remque instructions              */
  899. /**********************************************************************/
  900.  
  901. /*ARGSUSED*/
  902. void InsertDQ(fHead, fNewElem)
  903. register DQueuePtr      fHead, fNewElem;
  904. /* Insert at head of queue */
  905. {
  906. #ifdef vax
  907.     asm("   insque  (r10),(r11)");
  908. #ifdef lint
  909.     /* Dummy stuff for lint -- do not EVER compile this in */
  910.     fHead = fNewElem;
  911.     fNewElem = fHead;
  912. #endif lint
  913. #endif
  914. #ifdef sun
  915.     HoldSigs();
  916.  
  917.     fNewElem->next = fHead;
  918.     fNewElem->prev = fHead->prev;
  919.     fHead->prev = fNewElem;
  920.     (fNewElem->prev)->next = fNewElem;
  921.  
  922.     ReleaseSigs();
  923. #endif    
  924. }
  925.  
  926. /*ARGSUSED*/
  927. DQueuePtr RemoveDQ(fElem)
  928. register DQueuePtr      fElem;
  929. {
  930. #ifdef vax
  931.     asm("   remque  (r11),r0");
  932. #ifdef lint
  933.     /* Dummy stuff for lint -- do not EVER compile this in */
  934.     fElem = fElem;
  935.     return fElem;
  936. #endif lint
  937. #endif
  938. #ifdef sun
  939.  
  940.     HoldSigs();
  941.  
  942.     if (fElem->next == fElem ) {
  943.  
  944.     ReleaseSigs();
  945.  
  946.     return( (DQueuePtr) 0 );
  947.     }
  948.     (fElem->prev)->next = fElem->next;
  949.     (fElem->next)->prev = fElem->prev;
  950.  
  951.     ReleaseSigs();
  952.  
  953.     return( fElem );
  954. #endif
  955. }
  956.  
  957. #ifndef lint
  958. #ifdef vax
  959. #define ODBit(xxx) (1 << ODTag_/**/xxx)
  960. #endif
  961. #ifdef sun
  962. #define ODBit(xxx) (1 << (31 - ODTag_/**/xxx))
  963. #endif
  964. #else  lint
  965. #define ODBit(xxx) 1
  966. #endif lint
  967.  
  968. void UtilsInit()
  969. {
  970.     unsigned int        gcMask, i;
  971.     ODTag tempTag;
  972.     int tempInt;
  973.     tempInt = ODBit(frozen);
  974.     tempTag = *(ODTag *) &tempInt;
  975.     assert(tempTag.frozen);
  976.     KMDTrace("Portability", 3, "UtilsInit: setting bit masks\n");
  977.     gcMask              = 
  978.     ODBit(gcDoNotCollect)   |       ODBit(gcMark1)          |
  979.     ODBit(gcMark2)          |       ODBit(gcFrozen)         |
  980.     ODBit(localgcMark1)     |       ODBit(localgcMark2)     |
  981.     ODBit(xref);
  982.     
  983.     for (i=0; i < 32; i++) validMask[i] = 0;
  984.     validMask[(unsigned int) InvalidTag] = ~0;
  985.     validMask[(unsigned int) GODTag] =
  986.     ODBit(frozen)           |       ODBit(global)           |
  987.     ODBit(replicated)       |       ODBit(isResident)       |
  988.     ODBit(setUpDone)        |       ODBit(isFixed)          |
  989.     ODBit(inTransit)        |       ODBit(broken)           |
  990.     ODBit(seenHere)         |       gcMask;
  991.     validMask[(unsigned int) UnknownTag] =
  992.     validMask[(unsigned int) GODTag];
  993.     validMask[(unsigned int) GODataTag] =
  994.     ODBit(global)           |       ODBit(replicated)       |
  995.     ODBit(inTransit)        |       ODBit(broken)           |
  996.     gcMask;
  997.     validMask[(unsigned int) SSODTag] =
  998.     ODBit(frozen)           |       ODBit(isResident)       |
  999.     ODBit(inTransit)        |       ODBit(seenHere)         |
  1000.     gcMask;
  1001.     validMask[(unsigned int) SSTag] =
  1002.     ODBit(frozen)           |       gcMask;
  1003.     validMask[(unsigned int) CodeODTag] =
  1004.     ODBit(frozen)           |       ODBit(isResident)       |
  1005.     ODBit(setUpDone)        |       ODBit(inTransit)        |
  1006.     ODBit(allInstancesAreLocal)                             |
  1007.     ODBit(hasNoPointer)     |       ODBit(seenHere)         |
  1008.     gcMask;
  1009.     validMask[(unsigned int) CodeTag] =
  1010.     ODBit(setUpDone)        |       ODBit(allInstancesAreLocal) |
  1011.     ODBit(hasNoPointer)     |       gcMask;
  1012.     validMask[(unsigned int) LOTag] =
  1013.     ODBit(global)           |       ODBit(replicated)       |
  1014.     ODBit(broken)           |       gcMask;
  1015.     validMask[(unsigned int) ProcessODTag] = ~0; /* obsolete */
  1016.     validMask[(unsigned int) AbConTag] =
  1017.     ODBit(global)           |
  1018.     ODBit(allInstancesAreLocal)                             |
  1019.     ODBit(hasNoPointer)     |       gcMask;
  1020.     validMask[(unsigned int) CondTag] =
  1021.     validMask[(unsigned int) GODTag];
  1022.     validMask[(unsigned int) DotoTag] =
  1023.     ODBit(seenHere)         |       gcMask;
  1024.  
  1025.     /* Check that we have got the Names of enumeration types right */
  1026.     if (strcmp(RTagNames[(int) LastRTag], "LastRTag")){
  1027.     ErrMsg("UtilsInit: Minor warning, RTagNames inconsistent\n");
  1028.     }
  1029.     
  1030.     if (strcmp(ITagNames[(int) LastITag], "LastITag")) {
  1031.     ErrMsg("UtilsInit: Minor warning, ITagNames inconsistent\n");
  1032.     }
  1033.     
  1034.     if (strcmp(SSRunStatusNames[(int) SSLastRunStatus], "LastRunStatus")) {
  1035.     ErrMsg("UtilsInit: Minor warning, SSRunStatusNames inconsistent\n");
  1036.     }
  1037.  
  1038.     if (strcmp(BasicTagName[(int) LastODBasicTag], "LastODBasicTag")) {
  1039.     ErrMsg("UtilsInit: Minor warning, BasicTagName inconsistent\n");
  1040.     }
  1041. }
  1042.  
  1043. /* Copyright 1986 Eric Jul */
  1044.